
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.JPanel;

public class SegmentsPanel  extends JPanel implements MouseListener, MouseMotionListener{
    
    private InformationPanel main;
    private int x_mpos, y_mpos; //Position de la souris sur le panel.
    private int x1, x2, y1, y2; //Points enregistré lors du dernier clic.
    private int x_offset, y_offset; //Offsets du aux déplacement du repère;
    private int gapx, gapy; //écart à affecter au repère;
    private int zoom;
    private boolean drawing, moving;
    private ArrayList<Point> intersections;
    private ArrayList<Line> segments;
    
    
    public SegmentsPanel(InformationPanel main){
        super();
        this.main = main;
        drawing = false;
        moving = false;
        zoom = 1;
        System.out.println("" + x_offset);
        intersections = new ArrayList<Point>();
        segments = new ArrayList<Line>();
        addMouseListener(this);
        addMouseMotionListener(this);
        setBackground(Color.WHITE);
    }
    
    public void zoomIn(){
        zoom = zoom + 1;
        repaint();
    }
    
    public void zoomOut(){
        if(zoom != 1){
            zoom = zoom - 1;
            repaint();
        }
    }
    
    public ArrayList<Line> getSegments(){
        return segments;
    }
    
    public void setSegments(ArrayList<Line> segments){
        this.segments = segments;
        main.setNumberOfSegments(segments.size());
        repaint();
    }
    
    public int getNumberOfSegments(){
        return segments.size();
    }
    
    public void setIntersections(ArrayList<Point> intersections){
        this.intersections = intersections;
        main.setNumberOfIntersections(intersections.size());
        repaint();
    }
    
    public void undo(){
        if(!segments.isEmpty()){
            segments.remove(segments.size() - 1);
            main.setNumberOfSegments(segments.size());
            repaint();
        }
    }
    
    public void clear(){
        intersections = new ArrayList<Point>();
        segments = new ArrayList<Line>();
        main.clear();
        repaint();
    }
    
    public void drawSegments(Graphics2D g2d, Color color){
        g2d.setColor(color);
        for(Line line: segments){
            int a = (int) Math.round(line.getX1() + line.getXOffset() + x_offset);
            int b = (int) Math.round(getHeight() / zoom - line.getY1() + line.getYOffset() + y_offset);
            int c = (int) Math.round(line.getX2() + line.getXOffset() + x_offset);
            int d = (int) Math.round(getHeight() / zoom - line.getY2() + line.getYOffset() + y_offset);
            g2d.drawLine(a, b, c, d);
        }
    }
    
    public void drawIntersections(Graphics2D g2d, Color color){
        //TODO Les points se trace parfois nimp (algo ou dessin ?)
        g2d.setColor(color);
        for(Point p: intersections){
            int a = (int) Math.round(p.getX() + x_offset - 1);
            int b = (int) Math.round(getHeight() / zoom - p.getY() + y_offset + 1);
            g2d.drawOval(a, b, 1, 1);
        }
    }
    
    public void drawPreview(Graphics2D g2d, Color color){
        g2d.setColor(color);
        int a = x1 / zoom;
        int b = y1 / zoom;
        int c = x2 / zoom;
        int d = y2 / zoom;
        g2d.drawLine(a, b, c, d);
    }
    
    public void drawLandmark(Graphics2D g2d, Color color){
        g2d.setColor(color);
        int vxtop = x_offset;
        int vxbottom = x_offset;
        int vytop = 0;
        int vybottom = getHeight() / zoom;
        int hxtop = 0;
        int hxbottom = getWidth();
        int hytop = getHeight() / zoom + y_offset;
        int hybottom = getHeight() / zoom + y_offset;
        g2d.drawLine(vxtop, vytop, vxbottom, vybottom);
        g2d.drawLine(hxtop, hytop, hxbottom, hybottom);
    }
    
    public void drawPosition(Graphics g, Color color){
        g.setColor(color);
        int xpos = x_mpos / zoom - x_offset;
        int ypos = (getHeight() - y_mpos) / zoom + y_offset;
        String text = String.format("(%d, %d)", xpos, ypos);
        g.drawString(text, x_mpos / zoom, y_mpos / zoom );
    }
    
    public void paintComponent(Graphics g){
        Graphics2D g2d = (Graphics2D) g;
        g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ));
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
        g2d.scale(zoom, zoom);
        super.paintComponent(g2d);
        drawLandmark(g2d, Color.GRAY);
        drawSegments(g2d, Color.BLACK);
        drawIntersections(g2d, Color.RED);
        if(drawing && !moving) drawPreview(g2d, Color.BLUE);
        drawPosition(g2d, Color.GRAY);
    }

    public void mouseClicked(MouseEvent me) {/*Not used*/}

    public void mousePressed(MouseEvent me) {
        x1 = me.getX();
        y1 = me.getY();
        if(me.getButton() == me.BUTTON1) drawing = true;
        if(me.getButton() == me.BUTTON3) moving = true;
    }

    public void mouseReleased(MouseEvent me) {
        if(me.getButton() == me.BUTTON1){
            x2 = me.getX();
            y2 = me.getY();
            if(x1 != x2 || y1 != y2){
                Point p1 = new Point(x1 / zoom, (getHeight() - y1) / zoom);
                Point p2 = new Point(x2 / zoom, (getHeight() - y2) / zoom);
                Line line = new Line(p1, p2);
                segments.add(line);
                line.setOffset(x_offset, y_offset);
                main.setNumberOfSegments(segments.size());
                drawing = false;
            }
        }
        else if(me.getButton() == me.BUTTON3){
            gapx= 0;
            gapy =  0;
            moving = false;
        }
        repaint();
    }

    public void mouseEntered(MouseEvent me) {/*Not used*/}

    public void mouseExited(MouseEvent me) {/*Not used*/}

    public void mouseDragged(MouseEvent me) {
        x_mpos = me.getX();
        y_mpos = me.getY();
        if(drawing){
            x2 = x_mpos;
            y2 = y_mpos;
            repaint();
        }
        else if(moving){
            System.out.println("xoffset: " + x_offset + "| gapx: " + gapx);
            System.out.println("yoffset: " + y_offset + "| gapy: " + gapy);
            x_offset = x_offset - gapx;
            y_offset = y_offset - gapy;
            gapx = x_mpos - x1;
            gapy = y_mpos - y1;
            x_offset = x_offset + gapx;
            y_offset = y_offset + gapy;
            repaint();
        }
    }

    public void mouseMoved(MouseEvent me) {
        x_mpos = me.getX();
        y_mpos = me.getY();
        repaint();
    }
    
}
